/**
 *	@file	pgtel_list.c
 *	@brief	ポケギア　電話帳リスト管理
 *	@author	Miyuki Iwasawa
 *	@date	07.10.24
 */

#include "common.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/wipe.h"
#include "system/buflen.h"
#include "gflib/touchpanel.h"
#include "application/app_tool.h"
#include "application/pokegear.h"
#include "msgdata/msg.naix"

#include "../pgear_sys.h"
#include "../pgear_frm.h"
#include "pgtel_sys.h"
#include "pgtel_bg.h"
#include "pgtel_sub.h"
#include "pgtel_key.h"

#include "pgtel_list.h"

static void tlist_Clear(PGTEL_NUMBER_LIST* pl);
static void list_LinkInit(PGTEL_SYS_WORK* wk);
static void vlisttag_Clear(PGTEL_LIST_TAG* tag);
static void vlist_BaseLineDraw(PGTEL_LIST_VIEW* pv,u8 line,u8 pat,BOOL put);
static void vlist_BaseDraw(PGTEL_LIST_VIEW* pv);
static void vlist_LineDraw(PGTEL_LIST_VIEW* pv,u8 line,u8 id,u8 sel_flag,BOOL put);
static void vlist_AllowActStSet(PGTEL_LIST_VIEW* pv);
static int vlist_LineScrollSet(PGTEL_LIST_VIEW* pv,u8 dir);
static int vlist_LineScrollWait(PGTEL_LIST_VIEW* pv);
static int vlist_PageScrollSet(PGTEL_LIST_VIEW* pv,u8 dir);
static int vlist_PageScrollWait(PGTEL_LIST_VIEW* pv);
static void vlist_ScrollWait(PGTEL_LIST_VIEW* pv);

static const PMTEL_BOOK dat;

#ifdef _NITRO
// 構造体が想定のサイズとなっているかチェック
SDK_COMPILER_ASSERT(sizeof(PMTEL_BOOK) == 20);
#endif

/**
 *	@brief	初期リストを作成
 */
void PGTelList_InitList(PGTEL_SYS_WORK* wk)
{
	//リスト用のメモリ確保(NewGame時から必ずおかあさん一人分は必ずEntryしている)
	wk->pBook = sys_AllocMemory(wk->heapID,sizeof(PGTEL_NUMBER_LIST)*wk->entryNum);

	list_LinkInit(wk);
}

/**
 *	@brief	リストの並びをセーブデータに反映してメモリ解放
 */
void PGTelList_ReleaseList(PGTEL_SYS_WORK* wk)
{
	u8 i = 0;
	PGTEL_NUMBER_LIST* pl;

	wk->tbook[i++] = wk->ps_book->number;	//最初の一個は絶対にある
	for(pl = wk->ps_book->next;pl != wk->ps_book;pl = pl->next){
		wk->tbook[i++] = pl->number;
	}
	//電話帳並べ替えデータ書き戻し
	PGearSv_PutTelBook(wk->sys->pg_save,wk->tbook,wk->entryNum);

	MI_CpuClear8(wk->pBook,sizeof(PGTEL_NUMBER_LIST)*wk->entryNum);
	sys_FreeMemoryEz(wk->pBook);
}

/**
 *	@brief	リストの並べ替え
 *
 *	@param	tp	挿入ターゲット
 *	@param	no	挿入位置
 */
void PGTelList_Insert(PGTEL_SYS_WORK* wk,PGTEL_NUMBER_LIST* tp,u8 no)
{
	int idx = 0;
	PGTEL_NUMBER_LIST*	pl;

	//tpをリストから外す
	tp->prev->next = tp->next;
	tp->next->prev = tp->prev;

	if(tp == wk->ps_book){	//spが最初だった場合、spの次が最初になる
		wk->ps_book = tp->next;
	}
	if(tp == wk->pe_book){	//spが最後だった場合、spの前が最後になる
		wk->pe_book = tp->prev;
	}
	if(no == (wk->entryNum-1)){	//最後にくっつけて終了
		tp->prev = wk->pe_book;
		tp->next = wk->pe_book->next;
		wk->pe_book->next = tp;
		wk->ps_book->prev = tp;
		wk->pe_book = tp;
		return;
	}

	pl = wk->ps_book;
	do{	//挿入場所をサーチ
		if(idx++ != no){
			pl = pl->next;
			continue;
		}
		//plの前に挿入
		tp->next = pl;
		tp->prev = pl->prev;
		tp->prev->next = tp;
		pl->prev = tp;
		if(pl == wk->ps_book){
			wk->ps_book = tp;
		}
		break;
	}while(pl != wk->ps_book);
#if 0
	//spをリストから外す
	sp->prev->next = sp->next;
	sp->next->prev = sp->prev;

	if(sp == wk->ps_book){	//spが最初だった場合、spの次が最初になる
		wk->ps_book = sp->next;
	}
	if(sp == wk->pe_book){	//spが最後だった場合、spの前が最後になる
		wk->pe_book = sp->prev;
	}
	if(dir == 0){
		//spをtpの前に挿入
		tp->prev->next = sp;
		sp->prev = tp->prev;
		tp->prev = sp;
		sp->next = tp;
		if(tp == wk->ps_book){
			wk->ps_book = sp;
		}
	}else{
		//spをtpの後ろに挿入
		tp->next->prev = sp;
		sp->next = tp->next;
		tp->next = sp;
		sp->prev = tp;

		if(tp == wk->pe_book){
			wk->pe_book = sp;
		}
	}
#endif
}

/**
 *	@brief	リストのオートソート
 */
void PGTelVList_AutoSort(PGTEL_SYS_WORK* wk,u8 mode)
{
	PMTEL_NUMBER tmp;
	int i,j;
	const PMTEL_BOOK* book;
	PGTEL_NUMBER_LIST* tp1,*tp2;

	book = wk->pTelSys->book;

	for(i = 0;i < wk->entryNum;i++){
		OS_Printf("SortKey %d -> %d , %d ,%d \n", i,
			book[wk->tbook[i]].sort_key[0],
			book[wk->tbook[i]].sort_key[1],
			book[wk->tbook[i]].sort_key[2]);
	}
	OS_Printf("mode %d\n",mode);
	for(i = 0;i< (wk->entryNum-1);i++){
		for(j = (wk->entryNum-1);j > i;j--){
			OS_Printf("i = %d,j = %d, i_key = %d, j_key = %d\n",
				i,j,book[wk->tbook[i]].sort_key[mode],book[wk->tbook[j]].sort_key[mode]);
			if(book[wk->tbook[j]].sort_key[mode] < book[wk->tbook[i]].sort_key[mode]){
				tmp = wk->tbook[i];
				wk->tbook[i] = wk->tbook[j];
				wk->tbook[j] = tmp;
			}
		}
	}
	//リストをつなぎなおす
	list_LinkInit(wk);

	//描画リスト再生成
	PGTelVList_VListMake(wk);
	wk->vList.top = wk->vList.pos = 0;
	PGTelVList_Start(wk,&wk->vList,wk->vList.top,wk->vList.pos);
}

/**
 *	@brief	Viewリスト構造体の初期化
 */
void PGTelVList_Init(PGTEL_SYS_WORK* wk)
{
	int i;
	PGTEL_LIST_VIEW* pv = &wk->vList;

	MI_CpuClear8(pv,sizeof(PGTEL_LIST_VIEW));

	for(i = 0;i < PMTEL_NUMBER_MAX;i++){
		vlisttag_Clear(&pv->tag[i]);
	}
	pv->count = wk->entryNum;	//制御数更新
	pv->win = &wk->win[WIN_LIST];
	pv->pSys = wk->pTelSys;	//データマネージャポインタ通知
	pv->line_pat = 0;

	pv->key_mode = &(wk->sys->key_mode);
	pv->input_f = &(wk->input_f);

	//アクターポインタの受け渡し
	for(i = 0;i < 2;i++){
		pv->pActA[i] = wk->pAct[TACT_ALLOWU+i];
	}
	for(i = 0;i < LIST_VIEW_MAX;i++){
		pv->pActS[i] = wk->pAct[TACT_SEL01+i];
	}
	for(i = 0;i < 4;i++){
		pv->pActC[i] = wk->pAct[TACT_CLU+i];
	}
	//リストフォントパレットNoセット
	pv->col[0].f1_col = LIST_COL01_FPAL1;
	pv->col[0].b1_col = LIST_COL01_BPAL1;
	pv->col[0].s1_col = LIST_COL01_SPAL1;
	pv->col[0].r1_col = LIST_COL01_RPAL1;
	pv->col[0].rs1_col = LIST_COL01_RSPAL1;
	pv->col[0].l1_col = LIST_COL01_LPAL1;
	pv->col[0].f2_col = LIST_COL01_FPAL2;
	pv->col[0].b2_col = LIST_COL01_BPAL2;
	pv->col[0].s2_col = LIST_COL01_SPAL2;
	pv->col[0].r2_col = LIST_COL01_RPAL2;
	pv->col[0].rs2_col = LIST_COL01_RSPAL2;
	pv->col[0].l2_col = LIST_COL01_LPAL2;
	pv->col[0].set1 = GF_PRINTCOLOR_MAKE(pv->col[0].f1_col,pv->col[0].s1_col,pv->col[0].b1_col);
	pv->col[0].set2 = GF_PRINTCOLOR_MAKE(pv->col[0].f2_col,pv->col[0].s2_col,pv->col[0].b2_col);
	pv->col[0].rset1 = GF_PRINTCOLOR_MAKE(pv->col[0].r1_col,pv->col[0].rs1_col,pv->col[0].b1_col);
	pv->col[0].rset2 = GF_PRINTCOLOR_MAKE(pv->col[0].r2_col,pv->col[0].rs2_col,pv->col[0].b2_col);

	pv->col[1].f1_col = LIST_COL02_FPAL1;
	pv->col[1].b1_col = LIST_COL02_BPAL1;
	pv->col[1].s1_col = LIST_COL02_SPAL1;
	pv->col[1].r1_col = LIST_COL02_RPAL1;
	pv->col[1].rs1_col = LIST_COL02_RSPAL1;
	pv->col[1].l1_col = LIST_COL02_LPAL1;
	pv->col[1].f2_col = LIST_COL02_FPAL2;
	pv->col[1].b2_col = LIST_COL02_BPAL2;
	pv->col[1].s2_col = LIST_COL02_SPAL2;
	pv->col[1].r2_col = LIST_COL02_RPAL2;
	pv->col[1].rs2_col = LIST_COL02_RSPAL2;
	pv->col[1].l2_col = LIST_COL02_LPAL2;
	pv->col[1].set1 = GF_PRINTCOLOR_MAKE(pv->col[1].f1_col,pv->col[1].s1_col,pv->col[1].b1_col);
	pv->col[1].set2 = GF_PRINTCOLOR_MAKE(pv->col[1].f2_col,pv->col[1].s2_col,pv->col[1].b2_col);
	pv->col[1].rset1 = GF_PRINTCOLOR_MAKE(pv->col[1].r1_col,pv->col[1].rs1_col,pv->col[1].b1_col);
	pv->col[1].rset2 = GF_PRINTCOLOR_MAKE(pv->col[1].r2_col,pv->col[1].rs2_col,pv->col[1].b2_col);
}

/**
 *	@brief	Viewリスト　描画リスト生成
 */
void PGTelVList_VListMake(PGTEL_SYS_WORK* wk)
{
	int i;
	PGTEL_NUMBER_LIST* pl;
	PGTEL_LIST_VIEW* pv = &wk->vList;

	pl = wk->ps_book;
	for(i = 0;i < pv->count;i++){
		pv->tag[i].id = i;
		pv->tag[i].number = pl->number;
		pv->tag[i].pl = pl;
		pl = pl->next;
	}
}

/**
 *	@brief	Viewリスト　制御スタート
 */
void PGTelVList_Start(PGTEL_SYS_WORK* wk,PGTEL_LIST_VIEW* pv,u8 vtop,u8 pos)
{
	int i,ct;

	ct = 0;
	if(vtop >= pv->count){
		vtop = 0;
	}
	//背景描画
	vlist_BaseDraw(pv);

	pv->vnum = 0;
	pv->top = vtop;
	pv->target = 0xFF;
	IWASAWA_PRINT(" ListMake\n");
	for(i = vtop,ct = 0;ct < LIST_VIEW_MAX;i++,ct++){
		if(i >= pv->count){
			pv->bottom = i-1;
			pv->vnum = ct;
			break;
		}
		vlist_LineDraw(pv,ct+1,i,FALSE,FALSE);
		IWASAWA_PRINT(" ->Entry %d ,id = %d \n",ct+1,i);
	}
	if(pv->vnum == 0){
		pv->vnum = ct;
		pv->bottom = ct-1+vtop;
	}
	if(pos >= pv->vnum){
		pos = 0;
	}
	pv->pos = pos;
	GF_BGL_BmpWinOn(pv->win);
	vlist_AllowActStSet(pv);
//	if(*pv->key_mode != PGKM_APPKEY || wk->is_call){
	if(wk->is_call){
		PGTelVList_CursorSet(pv,pos,FALSE);
	}else{
		PGTelVList_CursorSet(pv,pos,TRUE);
	}
}

/*
 *	@brief	項目選択カーソルの描画制御
 *
 *	@param	pos カーソルを表示するポジション
 *	@param	draw_f	描画フラグ
 */
void PGTelVList_CursorSet(PGTEL_LIST_VIEW* pv,u8 pos,BOOL draw_f)
{
	int i;

	if(draw_f){
		for(i = 0;i <4;i++){
			CLACT_SetDrawFlag(pv->pActC[i],TRUE);
		}
	}else{
		for(i = 0;i <4;i++){
			CLACT_SetDrawFlag(pv->pActC[i],FALSE);
		}
	}
	if(pos >= LIST_VIEW_MAX){
		pos = pv->pos;
	}
	if(pv->pos >= pv->vnum){
		pos = pv->pos =pv->vnum-1;
	}
	CATS_ObjectPosSet(pv->pActC[0],TACT_CL_PX1,TACT_CL_SY*pos+TACT_CL_PY);
	CATS_ObjectPosSet(pv->pActC[1],TACT_CL_PX1,TACT_CL_SY*pos+TACT_CL_PY+22);
	CATS_ObjectPosSet(pv->pActC[2],TACT_CL_PX2,TACT_CL_SY*pos+TACT_CL_PY);
	CATS_ObjectPosSet(pv->pActC[3],TACT_CL_PX2,TACT_CL_SY*pos+TACT_CL_PY+22);
}

/*
 *	@brief	項目選択カーソルのアニメ制御
 *
 *	@param	anm_on	アニメ有効/無効
 */
void PGTelVList_CursorAnimeSet(PGTEL_LIST_VIEW* pv,BOOL anm_on)
{
	int i;

	for(i = 0;i <4;i++){
		CLACT_SetAnmFlag(pv->pActC[i],anm_on);
		CLACT_SetDrawFlag(pv->pActC[i],TRUE);
	}
}

/**
 *	@brief	リストの並べ替えカーソルの描画制御
 */
void PGTelVList_SortCursorSet(PGTEL_LIST_VIEW* pv,u8 pos,BOOL draw_f)
{
	int i;

	if(draw_f){
		for(i = 0;i < pv->vnum;i++){
			CLACT_SetDrawFlag(pv->pActS[i],TRUE);
			if(pos == i){
				CLACT_AnmChg(pv->pActS[i],ANM_H_SORT2);
			}else{
				CLACT_AnmChg(pv->pActS[i],ANM_H_SORT);
			}
		}
	}else{
		for(i = 0;i < LIST_VIEW_MAX;i++){
			CLACT_SetDrawFlag(pv->pActS[i],FALSE);
		}
	}
}

/**
 *	@brief	制御モード切替
 */
void PGTelVList_ModeChange(PGTEL_LIST_VIEW* pv,u8 mode)
{
	if(mode == 0){	//通常モードに切替
		pv->mode = 0;
		PGTelVList_SortCursorSet(pv,0xFF,FALSE);
		PGTelVList_LineRewriteNormal(pv);

		PGTelVList_CursorSet(pv,pv->pos,TRUE);
	}else{	//ソートモードに切替
		pv->mode = 1;
		PGTelVList_SortCursorSet(pv,pv->pos,TRUE);
	}
}

/**
 *	@brief	項目選択カーソルの制御
 */
int PGTelVList_KeyIn(PGTEL_LIST_VIEW* pv)
{
	u8	target = 0;

	if(pv->scr_f){
		vlist_ScrollWait(pv);
		return -1;
	}
	if(pv->scr_ct){
		--pv->scr_ct;
		return -1;
	}
	target = pv->top+pv->pos;
	if(sys.trg & PAD_BUTTON_A){
		pv->target = target;
		vlist_LineDraw(pv,pv->pos+1,pv->target,TRUE,TRUE);

		Snd_SePlay(SE_PGEAR_DECIDE);
		return pv->target;
	}
	if(sys.repeat & PAD_KEY_UP){
		if( target <= 0 ){
			return -1;
		}
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		if(pv->pos == 0){
			if( target > 0){
				//スクロールダウン
				vlist_LineScrollSet(pv,1);
			}
			return -1;
		}
		//カーソル位置マイナス
		--pv->pos;
		PGTelVList_CursorSet(pv,pv->pos,TRUE);
		pv->scr_ct = 2;
		return -1;
	}
	if(sys.repeat & PAD_KEY_DOWN){
		if( target >= (pv->count-1)){
			return -1;
		}
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		if(pv->pos == 5){
			if(target < (pv->count-1)){
				//スクロールアップ
				vlist_LineScrollSet(pv,0);
			}
			return -1;
		}
		//カーソル位置プラス
		++pv->pos;
		PGTelVList_CursorSet(pv,pv->pos,TRUE);
		pv->scr_ct = 2;
		return -1;
	}
	if(sys.trg & PAD_KEY_LEFT){
		if(pv->top > 0){
			Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
			vlist_PageScrollSet(pv,1);
		}
		return -1;
	}
	if(sys.trg & PAD_KEY_RIGHT){
		if(pv->top+LIST_VIEW_MAX < pv->count){
			Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
			vlist_PageScrollSet(pv,0);
		}
		return -1;
	}
	return -1;
}

/**
 *	@brief	項目選択カーソルの制御 ソートモード
 */
int PGTelVList_KeyInSort(PGTEL_LIST_VIEW* pv)
{
	u8	target = 0;

	if(pv->scr_f){
		vlist_ScrollWait(pv);
		return -1;
	}
	if(pv->scr_ct){
		--pv->scr_ct;
		return -1;
	}
	target = pv->top+pv->pos;
	if(sys.trg & PAD_BUTTON_A){
		return target;
	}else if(sys.trg & PAD_BUTTON_B){
		return pv->target;
	}
	if(sys.repeat & PAD_KEY_UP){
		if(target <= 0){
			return -1;
		}
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		if(pv->pos == 0){
			if( target > 0){
				//スクロールダウン
				vlist_LineScrollSet(pv,1);
			}
			return -1;
		}
		//カーソル位置マイナス
		--pv->pos;
		PGTelVList_SortCursorSet(pv,pv->pos,TRUE);
		pv->scr_ct = 2;
		return -1;
	}
	if(sys.repeat & PAD_KEY_DOWN){
		if( target >= (pv->count-1)){
			return -1;
		}
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		if(pv->pos == 5){
			if( target < (pv->count-1)){
				//スクロールアップ
				vlist_LineScrollSet(pv,0);
			}
			return -1;
		}
		//カーソル位置プラス
		++pv->pos;
		PGTelVList_SortCursorSet(pv,pv->pos,TRUE);
		pv->scr_ct = 2;
		return -1;
	}
	if(sys.trg & PAD_KEY_LEFT){
		if(pv->top > 0){
			Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
			vlist_PageScrollSet(pv,1);
		}
		return -1;
	}
	if(sys.trg & PAD_KEY_RIGHT){
		if(pv->top+LIST_VIEW_MAX < pv->count){
			Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
			vlist_PageScrollSet(pv,0);
		}
		return -1;
	}
	return -1;
}

/**
 *	@brief	タッチの制御
 */
int PGTelVList_TouchIn(PGTEL_LIST_VIEW* pv)
{
	int ret;
	u8	target = 0;

	static const RECT_HIT_TBL TpRect[] = {
//		{0,191,0,255}, ty,by,lx,rx
		{LIST_TP_PY01,LIST_TP_PY01+LIST_TP_SY,LIST_TP_PL,LIST_TP_PR},
		{LIST_TP_PY02,LIST_TP_PY02+LIST_TP_SY,LIST_TP_PL,LIST_TP_PR},
		{LIST_TP_PY03,LIST_TP_PY03+LIST_TP_SY,LIST_TP_PL,LIST_TP_PR},
		{LIST_TP_PY04,LIST_TP_PY04+LIST_TP_SY,LIST_TP_PL,LIST_TP_PR},
		{LIST_TP_PY05,LIST_TP_PY05+LIST_TP_SY,LIST_TP_PL,LIST_TP_PR},
		{LIST_TP_PY06,LIST_TP_PY06+LIST_TP_SY,LIST_TP_PL,LIST_TP_PR},
		{SBTN_TP_PY01,SBTN_TP_PY01+SBTN_TP_SY,SBTN_TP_PL,SBTN_TP_PR},
		{SBTN_TP_PY02,SBTN_TP_PY02+SBTN_TP_SY,SBTN_TP_PL,SBTN_TP_PR},
		{RECT_HIT_END,0,0,0}
	};

	if(pv->scr_f){
		vlist_ScrollWait(pv);
		return -1;
	}

	ret = GF_TP_RectHitTrg(TpRect);
	if(	ret == RECT_HIT_NONE){
		return -1;
	}

	if(ret < LIST_VIEW_MAX && ret < pv->vnum){
		pv->pos = ret;	//ポジション更新
		pv->target = pv->top+ret;
		vlist_LineDraw(pv,pv->pos+1,pv->target,TRUE,TRUE);
		PGTelVList_CursorSet(pv,pv->pos,TRUE);
		Snd_SePlay(SE_PGEAR_DECIDE);
		return pv->target+1;	//スクロールボタンが0なので、+1でかえす
	}
	if(ret == 6 && (pv->top > 0)){
		vlist_PageScrollSet(pv,1);
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		return 0;
	}
	if(ret == 7 && (pv->top+LIST_VIEW_MAX < pv->count)){
		vlist_PageScrollSet(pv,0);
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		return 0;
	}
	return -1;
}

/**
 *	@brief	タッチの制御　ソートモード
 */
int PGTelVList_TouchInSort(PGTEL_LIST_VIEW* pv,BOOL* touch_f)
{
	int ret;
	u8	target = 0;

	static const RECT_HIT_TBL TpRect[] = {
//		{0,191,0,255}, ty,by,lx,rx
		{SORT_TP_PY01,SORT_TP_PY01+SORT_TP_SY,SORT_TP_PL,SORT_TP_PR},
		{SORT_TP_PY02,SORT_TP_PY02+SORT_TP_SY,SORT_TP_PL,SORT_TP_PR},
		{SORT_TP_PY03,SORT_TP_PY03+SORT_TP_SY,SORT_TP_PL,SORT_TP_PR},
		{SORT_TP_PY04,SORT_TP_PY04+SORT_TP_SY,SORT_TP_PL,SORT_TP_PR},
		{SORT_TP_PY05,SORT_TP_PY05+SORT_TP_SY,SORT_TP_PL,SORT_TP_PR},
		{SORT_TP_PY06,SORT_TP_PY06+SORT_TP_SY,SORT_TP_PL,SORT_TP_PR},
//		{SORT_TP_PY07,SORT_TP_PY07+SORT_TP_SY,SORT_TP_PL,SORT_TP_PR},
		{SBTN_TP_PY01,SBTN_TP_PY01+SBTN_TP_SY,SBTN_TP_PL,SBTN_TP_PR},
		{SBTN_TP_PY02,SBTN_TP_PY02+SBTN_TP_SY,SBTN_TP_PL,SBTN_TP_PR},
		{RECT_HIT_END,0,0,0}
	};

	if(pv->scr_f){
		vlist_ScrollWait(pv);
		return -1;
	}

	ret = GF_TP_RectHitTrg(TpRect);
	if(	ret == RECT_HIT_NONE){
		return -1;
	}

	if(ret < LIST_VIEW_MAX && ret < pv->vnum){
		pv->pos = ret;	//ポジション更新
		Snd_SePlay(SE_PGEAR_DECIDE);
		*touch_f = TRUE;
		return pv->top+ret;
	}
	if(ret == 6 && (pv->top > 0)){
		vlist_PageScrollSet(pv,1);
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		*touch_f = TRUE;
		return -1;
	}
	if(ret == 7 && (pv->top+LIST_VIEW_MAX < pv->count)){
		vlist_PageScrollSet(pv,0);
		Snd_SePlay(SE_PGEAR_MOVE_CURSOR);
		*touch_f = TRUE;
		return -1;
	}
	return -1;
}

/**
 *	@brief	選択したラインポジションを返す
 */
u8 PGTelVList_GetCurrentPos(PGTEL_LIST_VIEW* pv)
{
	return pv->pos;
}

/**
 *	@brief	カレントポジションセット
 */
void PGTelVList_SetCurrentPos(PGTEL_LIST_VIEW* pv,u8 pos)
{
	pv->pos = pos;
	PGTelVList_CursorSet(pv,pos,TRUE);
}

/**
 *	@brief	カレントラインをノーマル色で書き換える
 */
void PGTelVList_LineRewriteNormal(PGTEL_LIST_VIEW* pv)
{
	u8 target = pv->target;

	pv->target = 0xFF;	///<無効ナンバーをセット
	if(target >= pv->top && pv->bottom >= target){
		vlist_LineDraw(pv,(target-pv->top)+1,target,FALSE,TRUE);
	}
}

/*
 *	@brief	リスト構造体の初期化
 */
static void tlist_Clear(PGTEL_NUMBER_LIST* pl)
{
	pl->id = 0;
	pl->number = PMTEL_NUMBER_NULL;
	pl->prev = pl->next = NULL;
}

/**
 *	@brief	リンク初期化
 */
static void list_LinkInit(PGTEL_SYS_WORK* wk)
{
	int i;
	PGTEL_NUMBER_LIST* pl;

	wk->ps_book = wk->pe_book = NULL;

	//初期化
	for(i = 0;i< wk->entryNum;i++){
		pl = &wk->pBook[i];
		tlist_Clear(pl);

		pl->id = i;
		pl->number = wk->tbook[i];

		if(wk->ps_book == NULL){
			wk->ps_book = pl;
		}
		if(wk->pe_book == NULL){
			wk->pe_book = pl;
		}
		pl->prev = wk->pe_book;
		wk->pe_book->next = pl;
		wk->pe_book = pl;	//最後更新
	}

	//循環リストの最後を閉じる
	wk->pe_book->next = wk->ps_book;
	wk->ps_book->prev = wk->pe_book;
}

/*
 *	@brief	Vリストタグ初期化
 */
static void vlisttag_Clear(PGTEL_LIST_TAG* tag)
{
	tag->id = 0;
	tag->pl = NULL;
}

/**
 *	@brief	アドレスリストベース Bitmapライン描画
 */
static void vlist_BaseLineDraw(PGTEL_LIST_VIEW* pv,u8 line,u8 pat,BOOL put)
{
	u8	px,py;
	PGTEL_LIST_COL* col = &pv->col[pat];

	py = line*24;

	GF_BGL_BmpWinFill( pv->win,col->l1_col,0,py,LIST_L_SX,24);

	//ネームエリアベース描画
	GF_BGL_BmpWinFill( pv->win,col->b1_col,LIST_NM_PX,py,LIST_NM_SX,LIST_F_SY);
	//トレーナータイプベース描画
	GF_BGL_BmpWinFill( pv->win,col->b2_col,LIST_TR_PX,py,LIST_TR_SX,LIST_F_SY);

	//デザイン描画
	GF_BGL_BmpWinFill( pv->win,col->l2_col,1,py+1,2,2);
	GF_BGL_BmpWinFill( pv->win,col->l1_col,8,py,2,7);
	GF_BGL_BmpWinFill( pv->win,col->l1_col,9,py+9,2,2);
	GF_BGL_BmpWinFill( pv->win,col->l1_col,9,py+13,2,2);
	GF_BGL_BmpWinFill( pv->win,col->l1_col,9,py+17,2,2);

	if(put){
		GF_BGL_BmpWinOn(pv->win);
	}
}

/**
 *	@brief	アドレスリストベース　全体初期描画
 */
static void vlist_BaseDraw(PGTEL_LIST_VIEW* pv)
{
	int i;
	u8 pat = pv->line_pat;

	for(i = 0;i < LIST_LINE_MAX;i++){
		vlist_BaseLineDraw(pv,i,pat,FALSE);
		pat ^= 1;
	}
//	GF_BGL_BmpWinOn(pv->win);
}

static u8 vlist_LinePatGet(PGTEL_LIST_VIEW* pv,u8 line)
{
	if(pv->line_pat){
		return 1-(line%2);
	}else{
		return line%2;
	}
}

/**
 *	@brief	電話帳リスト ライン描画
 */
static void vlist_LineDraw(PGTEL_LIST_VIEW* pv,u8 line,u8 id,u8 sel_flag,BOOL put)
{
	u8	px,py;
	u8	pat;
	PGTEL_LIST_COL* col;
	PGTEL_LIST_TAG* tag;

	tag = &pv->tag[id];

	pat = vlist_LinePatGet(pv,line);
	col = &pv->col[pat];

	//ベース描画
	vlist_BaseLineDraw(pv,line,pat,FALSE);

	//項目描画
	py = line*24;

	if(sel_flag || id == pv->target){
		GF_STR_PrintColor(	pv->win,FONT_TOUCH,
							PMTelData_GetNameStr(pv->pSys,tag->number),
							LIST_NM_BPX,py+LIST_F_BPY,MSG_NO_PUT,col->rset1,NULL );
		GF_STR_PrintColor(	pv->win,FONT_SYSTEM,
							PMTelData_GetTrtypeStr(pv->pSys,tag->number),
							LIST_TR_BPX,py+LIST_F_BPY,MSG_NO_PUT,col->rset2,NULL );
	}else{
		GF_STR_PrintColor(	pv->win,FONT_TOUCH,
							PMTelData_GetNameStr(pv->pSys,tag->number),
							LIST_NM_BPX,py+LIST_F_BPY,MSG_NO_PUT,col->set1,NULL );
		GF_STR_PrintColor(	pv->win,FONT_SYSTEM,
							PMTelData_GetTrtypeStr(pv->pSys,tag->number),
							LIST_TR_BPX,py+LIST_F_BPY,MSG_NO_PUT,col->set2,NULL );
	}

	if(put){
		GF_BGL_BmpWinOn(pv->win);
	}
}

/*
 *	@brief	矢印カーソルの表示・非表示制御
 */
static void vlist_AllowActStSet(PGTEL_LIST_VIEW* pv)
{
	if(pv->top > 0){	//上向き矢印セット
		CLACT_SetDrawFlag(pv->pActA[0], TRUE);
	}else{
		CLACT_SetDrawFlag(pv->pActA[0], FALSE);
	}
	if(pv->top+LIST_VIEW_MAX < pv->count){
		CLACT_SetDrawFlag(pv->pActA[1], TRUE);
	}else{
		CLACT_SetDrawFlag(pv->pActA[1], FALSE);
	}
}

/**
 *	@brief	リストの一行スクロール
 */
static int vlist_LineScrollSet(PGTEL_LIST_VIEW* pv,u8 dir)
{
	if(dir){	//下方向
		if(pv->top < 1){
			return FALSE;
		}
		vlist_LineDraw(pv,0,--pv->top,FALSE,TRUE);
		--pv->bottom;
	}else{	//上方向
		if(pv->bottom >= (pv->count-1)){
			return FALSE;
		}
		vlist_LineDraw(pv,LIST_LINE_MAX-1,++pv->bottom,FALSE,TRUE);
		++pv->top;
	}
	IWASAWA_PRINT( "LineScroll dir=%d , top = %d ,bottom = %d\n",dir,pv->top,pv->bottom);

	pv->scr_ct = 0;
	pv->scr_dir = dir;
	pv->scr_f = 1;
	*pv->input_f = 1;
	pv->line_pat ^= 1;
	//矢印カーソルの状態も変更
	vlist_AllowActStSet(pv);
	return TRUE;
}

/**
 *	@brief	リストの一行スクロールウェイト
 */
static int vlist_LineScrollWait(PGTEL_LIST_VIEW* pv)
{
	if(pv->scr_dir){	//下方向
		GF_BGL_BmpWinShift( pv->win,GF_BGL_BMPWIN_SHIFT_D,8,0x00);
	}else{	//上方向
		GF_BGL_BmpWinShift( pv->win,GF_BGL_BMPWIN_SHIFT_U,8,0x00);
	}
	GF_BGL_BmpWinOn(pv->win);
	if(pv->scr_ct++ >= 2){
		pv->scr_ct = 0;
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	リストのページスクロールセット
 */
static int vlist_PageScrollSet(PGTEL_LIST_VIEW* pv,u8 dir)
{
	int ret;

	pv->scr_line = 0;
	pv->scr_kind = 1;
	pv->scr_dir = dir;
	pv->scr_f = 1;
	*pv->input_f = 1;

	ret = vlist_LineScrollSet(pv,dir);
	if(!ret){
		pv->scr_end = TRUE;
	}
	return FALSE;
}

/*
 *	@brief	リストのページスクロールウェイト
 */
static int vlist_PageScrollWait(PGTEL_LIST_VIEW* pv)
{
	if(!vlist_LineScrollWait(pv)){
		return FALSE;
	}
	if(	pv->scr_end ||
		pv->scr_line++ >= 5 ||
		(!vlist_LineScrollSet(pv,pv->scr_dir))){
		pv->scr_line = 0;
		pv->scr_kind = 0;
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	スクロール処理待ち
 *
 */
static void vlist_ScrollWait(PGTEL_LIST_VIEW* pv)
{
	int ret;
	if(pv->scr_kind){
		ret = vlist_PageScrollWait(pv);
	}else{
		ret = vlist_LineScrollWait(pv);
	}
	if(!ret){
		return;
	}
	*pv->input_f = 0;
	pv->scr_f = 0;
}

